#!/usr/bin/perl
## iaTsu.pl for  in /home/kizili_g//exo/zappy/roultabobitch-skl
## 
## Made by guillaume kizilian
## Login   <kizili_g@epitech.net>
## 
## Started on  Mon Jul 11 12:33:29 2011 guillaume kizilian
## Last update Sun Jul 17 17:02:42 2011 aurelien dorey
##

use Switch;
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval nanosleep
clock_gettime clock_getres clock_nanosleep clock
stat );

my $TsuLevelIncant = ((1,0,0,0,0,0),
		      (1,1,1,0,0,0),
		      (2,0,1,0,2,0),
		      (1,1,2,0,1,0),
		      (1,2,1,3,0,0),
		      (1,2,3,0,1,0),
		      (2,2,2,2,2,1));
my $TsuIdent = int(rand(899)) + 100;
my $TsuLevel = 1;
my $TsuDead : shared = 0; # Suis-je en Vie?
my $TsuNumClient = 0; #Nombre de clients;
my %Tsumodes = ('NORMAL' => 1,
		'ATTACK' => 2,
		'SEARCHINCANT' =>  3,
		'SURVIVE' => 4,
		'FIRSTUP' => 5,
		'WAITPEOPLE' => 6); # Liste des Modes

my $Tsumode : shared = $Tsumodes{'NORMAL'}; # Mode courant
my $TsuRestart = 0;
# Variables Map
my $TsumapX = 0; #Largeur Map
my $TsumapY = 0; #Hauteur Map
my $TsuInf; # TsuInf est le plus petit entre largeur et hauteur de la map;

# Variables Champs Vision
my $TsuLargVision = 3;# 3 + (2 * (Level - 1));
my $TsuNbCase = 4;# +=( 3 + (2 * (Level - 1))); #Nombre de case visible
my $TsuWalkFront = 0; # Nombre de case marcher dans le sens de parse
my $TsuFrontCase = ($TsuLevel * ($TsuLevel - 1)) + (2 * ($TsuLevel - 1)) + 2; #Case la plus devant possible en fonction du champ de vision
#  Variables Parsing retour 'voir'
my $TsuTarget = 0;
my $TsuAvance = 0;
my $TsuRight = 0; # Inferieur a 0 = a gauche
my $TsuOldAvance = 0;
my $TsuOldRight = 0;
my $TsuK = 0;
my $TsuIdentAim : shared = 0;
my $TsuLowFood = 8; #niveau critique de nourriture
my $TsuTotalSkuat : shared = 0;
my @TsuListSkuat : shared = (0, 1, 1, 3, 3, 5, 5); #S'obtiens avec [$TsuLevel - 1];
my $TsuSearchCase = "nourriture";

my $TsuFake : shared = "";

#  Variables Ressources
#  --Inventaire / Max par Niveau--
my %TsuRes : shared = ("nourriture" , 0,
	      "deraumere"  , 0,
	      "linemate"   , 0, 
	      "sibur"      , 0, 
	      "mendiane"   , 0, 
	      "phiras"     , 0, 
	      "thystame"   , 0,
	      "joueur"     , 0);

my %TsuMax = ("nourriture" , (50, 50, 50, 50, 50, 50, 50, 100),
	      "xnourriture" , (50, 50, 50, 50, 50, 50, 50, 100),
	      "deraumere", ( 8, 8, 7, 7, 6, 4, 2, 10),
	      "xderaumere", ( 8, 8, 7, 7, 6, 4, 2, 10),
	      "linemate" , ( 9, 8, 7, 5, 4, 3, 2, 10),
	      "xlinemate" , ( 9, 8, 7, 5, 4, 3, 2, 10),
	      "sibur"    , (10,10, 9, 8, 6, 5, 2, 10),
	      "xsibur"    , (10,10, 9, 8, 6, 5, 2, 10),
	      "mendiane" , ( 5, 5, 5, 5, 5, 2, 2, 20),
	      "xmendiane" , ( 5, 5, 5, 5, 5, 2, 2, 20),
	      "phiras"   , ( 6, 6, 6, 4, 3, 3, 2, 20),
	      "xphiras"   , ( 6, 6, 6, 4, 3, 3, 2, 20),
	      "thystame" , ( 1, 1, 1, 1, 1, 1, 1, 10),
	      "xthystame" , ( 1, 1, 1, 1, 1, 1, 1, 10),
	      "joueur"   , ( 0, 0, 0, 0, 0, 0, 0, 0));


# Empeche une Incantation
sub TsuAttack()
{
    while ($Tsumode == $Tsumodes{'ATTACK'}) {
	TsuVerif();
    }
}

# Recuperer les parametres au serveur
sub TsuConfig()
{
    my $Tsutemp;
    my $ret, $ret2;

    while ($Tsutemp ne "BIENVENUE\n") {
	$Tsutemp = shift_inline();
    }
    $tmp_send = $team;
    add_outline();
    {
	while (!(($ret) = ($Tsutemp =~ /^([0-9]+)\n$/))) {
	    $Tsutemp = shift_inline();
	}
	$TsuNumClient = $ret;
    }
    while (!(($ret, $ret2) = ($Tsutemp =~ /^([0-9]+) ([0-9]+)\n$/))) {
	$Tsutemp = shift_inline();
    }
    $TsumapX = $ret;
    $TsumapY = $ret2;
    if ($TsumapX > $TsumapY) {
	$TsuInf = $TsumapY;
    }
    else {
	$TsuInf = $TsumapX;
    }
}


# Verifie que le mode ne doit pas changer
# Si le mode doit changer ajouter clear_outline() ou clear_all();
sub TsuVerif()
{
    my $sec;
    my $msec;

    if ($TsuLevel == 1 && $TsuRes{'linemate'} >= 1 && $TsuRes{'nourriture'} >= 10) {
	clear_outline();
	{
	    lock($Tsumode);
	    $Tsumode = $Tsumodes{'FIRSTUP'};
	}
	$tmp_send = "voir";
	add_outline();
    } elsif ($TsuRes{'nourriture'} < $TsuLowFood) {
	clear_outline();
	{
	    lock($Tsumode);
	    $Tsumode = $Tsumodes{'SURVIVE'};
	}
	$tmp_send = 'voir';
	add_outline();
    } elsif ($TsuLevel == 2 && $TsuRes{'linemate'} >= 1 && $TsuRes{'deraumere'} >= 1
	     && $TsuRes{'sibur'} && $TsuRes{'nourriture'} >= 10 ) {
	($sec, $msec) = gettimeofday();
	$tmp_send = 'broadcast :' . $sec . ':'.  $TsuIdent . ':2\n';
	add_outline();
    }
}

sub TsuClearLoop()
{
    while (42) {
	while ($#in_line + 1 > 0 && $in_line[0] =~ /^(?:ok|ko)/ &&
	       $transit[0] =~ /^(?:incantation|voir|avance|prend|pose|gauche|droite|broadcast|fork|inventaire)/)
	{
	    $transit[0] =~ m/^(prend|pose) (.*)$/;
	    if ($in_line[0] eq "ok\n" &&
		$transit[0] =~ m/^(prend|pose) (.*)$/) {
		if ($1 eq "prend") {
		    lock(%TsuRes);
		    $TsuRes{$2} += 1;
		} elsif ($1 eq "pose" && $TsuRes{$2} > 0){
		    lock(%TsuRes);
		    $TsuRes{$2} -= 1;
		}
	    }
	    if ($in_line[0] eq "ko\n" &&
		$transit[0] eq "incantation") {
		lock($Tsumode);
		$Tsumode = $Tsumodes{'NORMAL'};
	    }
	    if ($in_line[0] eq "ko\n" &&
		$transit[0] =~ m/^niveau actuel : ([0-9]+)\n$/) {
		TsuLevelUp($1);
		lock($Tsumode);
		$Tsumode = $Tsumodes{'NORMAL'};
	    }
	    {
		lock(@in_line);
		shift(@in_line);
	    }
	    {
		lock(@transit);
		shift(@transit);
	    }
	}
	if ($#in_line + 1 > 0 && $in_line[0] eq "clearit") {
		lock(@in_line);
		shift(@in_line);
	}
    }
}

sub TsuInventory
{
    $tmp_send = "inventaire";
    add_outline();
}

#	___MODULE DE VERIFICATION DES RETOURS PARTICULIERS___
#	\___________________________________________________/


sub TsuReplySkuat {
    my $sec, $msec;
    my ($send_id) = @_;

    if ($TsuRes{'nourriture'} > $TsuLowFood)
    {
	($sec, $msec) = gettimeofday();
	$tmp_send = 'broadcast :' . $sec . ':' . $TsuIdent . ':' . $send_id . 'go' ;
	add_outline();
    }
}

sub TsuAcceptSkuat {
    my $sec, $msec;
    my ($send_id, $rec_id) = @_;

    if (int($rec_id) == $TsuIdent)
    {
	($sec, $msec) = gettimeofday();
	$tmp_send = 'broadcast :' . $sec . ':' . $TsuIdent . ':' . $send_id . 'br' ;
	add_outline();
	{
	    lock($TsuTotalSkuat);
	    $TsuTotalSkuat += 1;
	}
	if ($TsuTotalSkuat == $TsuListSkuat[$TsuLevel - 1]) {
	    ($sec, $msec) = gettimeofday();
	    $tmp_send = 'broadcast :' . $sec . ':' . $TsuIdent . ':ch' ;
	    add_outline();
	    {
		lock($Tsumode);
		$Tsumode = $Tsumodes{'WAITPEOPLE'};
	    }
	}
    }
}

sub TsuLetsUp {
    my ($send_id, $k) = @_;

    if (int($send_id) == $TsuIdent)
    {
	$TsuK = $k;
	lock(@Tsumode);
	$Tsumode = $Tsumode{'SEARCHINCANT'};
    }
}

sub TsuBeReady {
    my ($send_id, $rec_id) = @_;

    if (int($rec_id) == $TsuIdent) {
	lock($TsuIdentAim);
	$TsuIdentAim = $send_id;
    }
}

# Parse le broadcast pour reagir en consequence.
sub TsuMessage
{
    my ($k, $mess) = @_;
    my $sec, $msec;
    my $send_id;
    my $mess;

    if ($TsuLevel != 1 && $mess =~ m/^:([0-9]+):([0-9]+):(.+)$/) {
	($sec, $msec) = gettimeofday();
	$send_id = $2;
	$mess = $3;
	if (int($1) - $sec < 20) {
	    switch($mess) {
		case "$TsuLevel" {TsuReplySkuat($send_id)}
		case m/([0-9]+)go$/ {TsuAcceptSkuat($send_id, $1)}
		case m/([0-9]+)br$/ {TsuBeReady($send_id, $1)}
		case 'ch' {TsuLetsUp($send_id, $k)}
	    }
	}
    } elsif ($TsuLevel != 1) {
	lock($TsuFake);
	$TsuFake = $mess;
    }
}

#Recuperer l'inventaire pour le stocker
sub TsuInvent {
    my ($i) = @_;
    my $line = $in_line[$i];

    {
	lock(@in_line);
	$in_line[$i] = "ok";
    }

    if ($line =~ m/{?nourriture ([0-9]+),linemate ([0-9]+),deraumere ([0-9]+),sibur ([0-9]+),mendiane ([0-9]+),phiras ([0-9]+),thystame ([0-9]+)}?/)
    {
	lock(%TsuRes);
	$TsuRes{"nourriture"} = $1;
	$TsuRes{"linemate"} = $2;
	$TsuRes{"deraumere"} = $3;
	$TsuRes{"sibur"} = $4;
	$TsuRes{"mendiane"} = $5;
	$TsuRes{"phiras"} = $6;
	$TsuRes{"thystame"} = $7;
    }
}

#Verifie Si un niveau a ete valide
sub TsuLevelUp {
    my ($r_lvl) = @_;

    if (int($r_lvl) > $TsuLevel) {
	$TsuLevel += 1;
	$TsuLargVision += 2;
	$TsuNbCase += (3 + (2 * ($TsuLevel - 1)));
	$TsuFrontCase = ($TsuLevel * ($TsuLevel - 1)) + (2 * ($TsuLevel - 1)) + 2;
    }
}

# Verifie si un evenement prioritaire arrive (Thread Reserve)
sub TsuVerifLoop()
{
    my $th;
    my $i = 0;
    
    while (42) {
	for ($i = 0; $#in_line + 1 > $i; $i++) {
	    if ($in_line[$i] =~ m/^message ([0-8]),(.*)\n$/) {
		{
		    lock(@in_line);
		    $in_line[$i] = "clearit";
		}
		if ($Tsumode == $Tsumodes{'NORMAL'}
		    || $Tsumode == $Tsumodes{'WAITPEOPLE'}
		    || $Tsumode == $Tsumodes{'SEARCHINCANT'}) {
		    TsuMessages($1, $2);
		}
	    } elsif ($in_line[$i] =~ m/^{.+[0-8]+.+}\n$/) {
		$th = threads->new(\&TsuInvent, $i);
		$th->detach;
	    } elsif ($in_line[$i] eq "mort\n") {
		{
		    lock($TsuDead);
		    $TsuDead = 1;
		}
		print 'Dommage t\'es mort level : ' . $TsuLevel . "\n";
		exit (0);
	    } elsif ($in_line[$i] =~ m/^niveau actuel : ([0-9]+)\n/) {
		{
		    lock(@in_line);
		    $in_line[$i] = "clearit";
		}
		{
		    lock($Tsumode);
		    $Tsumode = $Tsumode{'NORMAL'};
		}
		TsuLevelUp($1);
	    }
	}
    }
}


#	!___MODULE DE VERIFICATION DES RETOURS PARTICULIERS___!




#	___MODULE D INCANTATION___
#	\________________________/

# Organise une Incantation
sub TsuIncant()
{
    while ($Tsumode == $Tsumodes{'INCANT'}) {
	TsuFindIncant();
    }
}
#	!___MODULE D INCANTATION___!


#	___MODULE DE RECHERCHE DE POINT D'EMISSIONL___
#	\____________________________________________/

sub TsuDeplaceIncant()
{
    my $depRight;
    my $depFront;

    $depRight = $TsuRight;
    $depFront = $TsuAvance;
    if ($depRight > 0) {
	$tmp_send = "droite";
	add_outline();
	for (; $depRight > 0 && $TsuRestart != 1; $depRight--) {
	    $tmp_send = "avance";
	    add_outline();
	}
	$tmp_send = "gauche";
	add_outline();
    } elsif ($depRight < 0) {
	$tmp_send = "gauche";
	add_outline();
	for (; $depRight < 0 && $TsuRestart != 1; $depRight++) {
	    $tmp_send = "avance";
	    add_outline();
	}
	$tmp_send = "droite";
	add_outline();
    }
    while ($depFront > 0 && $TsuRestart != 1) {
	$tmp_send = "avance";
	add_outline();
	$depFront--;
    }
}

sub getNewK()
{
    switch ($TsuK){
	case [3, 5, 7] {return $TsuFrontCase}
	case [4, 6] {return $TsuNbCase - 1}
    }
}

sub TsuCheckIncant
{
    my ($line) = @_;
    my @cases = ();
    
    @cases = split /[ ,]/, $line;
    for (my $n = 0; ($n < $#cases + 1) && $TsuRestart != 1; $n++) {
	print "N : $n ---> '$cases[$n]'\n";
	if ($cases[$n] eq $TsuSearchCase) {
	    $TsuTarget = $n;
	    TsuDeplaceIncant();
	    
	}
    }
}

sub TsuIsIncant()
{
    my $i = 0;

    $tmp_send = 'voir';
    add_outline();
    while ($Tsumode == $Tsumodes{'SEARCHINCANT'}) {
	for ($i = 0; ($Tsumode == $Tsumodes{'SEARCHINCANT'})
	     && ($#in_line + 1 > $i) && $TsuRestart != 1 ; $i++)
	{
	    if ($in_line[$i] =~ /^\{([^0-9]+)\}$/) {
		TsuCheckIncant($1);
		lock(@in_line);
		$in_line[$i] = "ok";
		return 0;
	    }
	}
    }
    return 1;
}

sub TsuFindIncant()
{
    if ($TsuK == 2 || $TsuK == 3){
	$tmp_send = "gauche";
	add_outline();
    } elsif ($TsuK == 4 && $TsuK == 5){
	$tmp_send = "gauche";
	add_outline();
	$tmp_send = "gauche";
	add_outline();
    } elsif ($TsuK == 6 && $TsuK == 7){
	$tmp_send = "droite";
	add_outline();
    }
    $TsuTarget = getNewK();
    TsuGetDist();
    while (TsuIsIncant() == 0 && $TsuRestart != 1) {
	TsuDeplaceIncant();
    }
    $TsuRight = 0;
    $TsuAvance = 0;
    $TsuK = 0;
    while ($Tsumodes{'SEARCHINCANT'}) {
	
    }
}

#	!___MODULE DE RECHERCHE DE POINT D'EMISSIONL___!



#	___MODULE DE RECHERCHE DE RESSOURCES OU MODE NORMAL___
#	\____________________________________________________/

#Calcule le parcours pour aller jusqu a une target du champs de vision
sub TsuGetDist ()
{
    my $tmp_pos1 = 0;
    my $tmp_pos2 = 0;
    my $add_middle = 2;
    my $add_left = 1;
    my $avance = 0;
    my $i = 0;

    $TsuOldAvance = $TsuAvance;
    $TsuOldRight = $TsuRight;
    for ($avance = 0;
	 !($TsuTarget >= $tmp_pos1 && $TsuTarget < ($tmp_pos1 + $add_left));
	$avance++)
    {
	$tmp_pos1 += $add_left;
	$add_left += 2;
	$tmp_pos2 += $add_middle;
	$add_middle += 2;
    }
    $TsuRight = ($TsuTarget - $tmp_pos2);
    $TsuAvance = $avance;
}


# Deplace jusqu'a Target_pos;
sub TsuDeplaceTo()
{
    my $depRight;
    my $depFront;

    TsuGetDist();
    $depRight = $TsuRight - $TsuOldRight;
    $depFront = $TsuAvance - $TsuOldAvance;
    if ($depRight > 0) {
	$tmp_send = "droite";
	add_outline();
	for (; $depRight > 0; $depRight--) {
	    $tmp_send = "avance";
	    add_outline();
	}
	$tmp_send = "gauche";
	add_outline();
    } elsif ($depRight < 0) {
	$tmp_send = "gauche";
	add_outline();
	for (; $depRight < 0; $depRight++) {
	    $tmp_send = "avance";
	    add_outline();
	}
	$tmp_send = "droite";
	add_outline();
    }
    $TsuWalkFront += $TsuAvance;
    while ($depFront > 0) {
	$tmp_send = "avance";
	add_outline();
	$depFront--;
    }
}

#   Decale de 1/2 du champs de vision dc (GAUCHE AVANCE ... AVANCE DROITE
sub TsuDecale()
{
    my $TsuLargDep = $TsuLargVision;
    $tmp_send = "droite";
    add_outline();
    while ($TsuLargDep > 0)
    {
	$TsuLargDep -= 1;
	$tmp_send = "avance";
	add_outline();
    }
    $tmp_send = "gauche";
    add_outline();
}

#Regarde ce qui est interessant sur la Map
sub TsuCheckMap
{
    my ($line) = @_;
    my @cases = ();
    my @res = ();
    
    @cases = split /,/, $line;
    for (my $n = 0; $n < $#cases + 1; $n++) {
	@res = split /[ ]+/, $cases[$n];
	for (my $m = 0; $m < ($#res + 1); $m++) {
	    if ($res[$m] ne "" && int($TsuRes{$res[$m]})
		< int(($TsuMax{$res[$m]})[$TsuLevel - 1])) {
		if ($TsuTarget != $n) {
		    $TsuTarget = $n;
		    TsuDeplaceTo();
		}
		$tmp_send = 'prend ' . $res[$m];
		add_outline();
	    }
	}
    }
    if ($TsuDead == 0) {
	$TsuTarget -= int($TsuNbCase / 2);
	TsuDeplaceTo();
	$TsuTarget = 0;
	$TsuAvance = 0;
	$TsuRight = 0;
    }
}


#Attends le retour de vision et cherche ce qui l'interesse
sub TsuWaitWatchAndAct()
{
    my $i = 0;

    while ($Tsumode == $Tsumodes{'NORMAL'} && $TsuDead == 0) {
	for ($i = 0; $Tsumode == $Tsumodes{'NORMAL'} && $TsuDead == 0
	     && $#in_line + 1 > $i; $i++)
	{
	    if ($in_line[$i] =~ /^\{([^0-9]+)\}$/) {
		TsuCheckMap($1);
		lock(@in_line);
		$in_line[$i] = "ok";
		return 0;
	    }
	}
    }
}

# Explore la map
sub TsuSearch()
{
    my $nb_loop = 0;
    my $th;

    print "\t\tNORMAL\n";
    clear_all();
    $tmp_send = "inventaire";
    add_outline();
    while ($Tsumode == $Tsumodes{'NORMAL'}) {
	$tmp_send = "voir";
	add_outline();
	TsuWaitWatchAndAct();
	last if ($Tsumode != $Tsumodes{'NORMAL'});
	TsuVerif();
	last if ($Tsumode != $Tsumodes{'NORMAL'});
	if ($TsuWalkFront >= $TsuInf) {
	    TsuDecale();
	    $TsuWalkFront = 0;
	}
	$nb_loop++;
	if ($nb_loop == 6) {
	    TsuInventory();
	    $nb_loop = 0;
	}
    }
}
#	!___MODULE DE RECHERCHE DE RESSOURCES OU MODE NORMAL___!


#	___MODULE POUR L ELEVATION DU LEVEL 1 AU LEVEL 2___
#	\_________________________________________________/

sub	TsuFirstUp
{
    my @cases = ();
    my @res = ();
    my $i = 0;
    my $zz = 0;

    print "\t\tFIRSTUP\n";
    while ($Tsumode == $Tsumodes{'FIRSTUP'}) {
	usleep(50);
	$zz += 1;
	if ($zz == 10000) {
	    $zz = 0;
	    print "Toujours en FIRSTUP\n";
	}
	if ($#in_line + 1 > 0 && $in_line[0] =~ m/^\{([^0-9]+)\}$/) {
	    @cases = split /,/, $1;
	    @res = split /[ ]+/, $cases[0];
	    {
		lock(@in_line);
		$in_line[0] = "ok";
	    }
	    if ($cases[0] !~ m/joueur.+joueur/) {
		for (my $m = 0; $m < ($#res + 1); $m++) {
		    if ($res[$m] ne "" && $res[$m] ne "joueur") {
			$tmp_send = 'prend ' . $res[$m];
			add_outline();
		    }
		}
		$tmp_send = 'pose linemate';
		add_outline();
		$tmp_send = 'incantation';
		add_outline();
		while ($transit[0] ne 'incantation'
		       && $Tsumode == $Tsumodes{'FIRSTUP'}) {
		    usleep(50);
		}
		for ($i = 0; $i < $#in_line + 1; $i++) {
		    if ($in_line[$i] eq "elevation en cours\n") {
			print "j'ai recu";
			{
			    lock(@in_line);
			    $in_line[$i] = 'ok';
			}
			{
			    lock($Tsumode);
			    $Tsumode = $Tsumodes{'NORMAL'};
			}
		    }
		}
		if ($Tsumode != $Tsumodes{'FIRSTUP'}) {
		    print "OUT BY RETURN\n";
		    return (0);
		}
	    }
	    $tmp_send = 'avance';
	    add_outline();
	    $tmp_send = 'voir';
	    add_outline();
	}
    }
}

#	!___MODULE POUR L ELEVATION DU LEVEL 1 AU LEVEL 2___!

#	___MODULE DE SURVIE___
#	\____________________/

#Ne recupere que la nourriture sur la Map
sub TsuCheckFood
{
    my ($line) = @_;
    my @cases = ();
    my @res = ();

    @cases = split /,/, $line;
    for (my $n = 0; $n < $#cases + 1; $n++) {
	print "\t\tfood_loop\n";
	if ($cases[$n] =~ m/nourriture/) {
	    if ($TsuTarget != $n) {
		$TsuTarget = $n;
		TsuDeplaceTo();
	    }
	    $tmp_send = 'prend nourriture';
	    add_outline();
	}
    }
    if ($TsuDead == 0) {
	$TsuTarget -= int($TsuNbCase / 2);
	TsuDeplaceTo();
	$TsuTarget = 0;
	$TsuAvance = 0;
	$TsuRight = 0;
    }
}

# Ne Parse que la nourriture jusqu'a sorti du niveau critique
sub TsuSurvive()
{
    my $i = 0;
    my $nb_loop = 0;

    clear_all();
    print "\t\tSURVIVE\n";
    $tmp_send = 'voir';
    add_outline();
    while ($Tsumode == $Tsumodes{'SURVIVE'} && $TsuDead == 0) {
	for ($i = 0; $Tsumode == $Tsumodes{'SURVIVE'} && $TsuDead == 0
	     && $#in_line + 1 > $i; $i++)
	{
	    if ($in_line[$i] =~ m/^\{([^0-9]+)\}$/) {
		TsuCheckMap($1);
		lock(@in_line);
		$in_line[$i] = 'ok';
	    }
	    if ($TsuRes{'nourriture'} > $TsuLowFood) {
		{
		    lock($Tsumode);
		    $Tsumode == $Tsumode{'NORMAL'};
		    $tmp_send = 'voir';
		    add_outline();
		}
	    }
	}
	if ($nb_loop == 10) {
	    TsuInventory();
	    $nb_loop = 0;
	}
	$nb_loop++;
    }
}

#	!___MODULE DE SURVIE___!

#	___BOUCLE PRINCIPALE DE L IA TSU___
#	\_________________________________/

sub TsuLoop()
{
    TsuConfig();
    $nb_send = 0;
    my $th;

    $th = threads->new(\&TsuClearLoop);
    $th->detach;
    $th = threads->new(\&TsuVerifLoop);
    $th->detach;
    while ($Tsudead != 1)
    {
	switch ($Tsumode) {
	    case ($Tsumodes{'SEARCHINCANT'}) {TsuFindIncant()}
	    case ($Tsumodes{'INCANT'}) {TsuIncant()}
	    case ($Tsumodes{'ATTACK'}) {TsuAttack()}
	    case ($Tsumodes{'SURVIVE'}) {TsuSurvive()}
	    case ($Tsumodes{'FIRSTUP'}) {TsuFirstUp()}
	    else { TsuSearch() }
	}
    }
}

TsuLoop();
